package com.wutuo.aggragation.rollcall.util;

import cn.apestar.agg.user.info.service.UserService;
import cn.apestar.base.SpringContextHolder;
import cn.apestar.user.provider.info.domain.User;
import com.wutuo.aggragation.rollcall.domain.Task;
import com.wutuo.aggragation.rollcall.domain.TaskDetail;
import com.wutuo.aggragation.rollcall.enums.SignActionType;
import com.wutuo.aggragation.rollcall.response.AddRollCallTaskResponse;
import com.wutuo.aggragation.rollcall.vo.*;
import com.wutuo.aggragation.user.vo.TeacherVo;
import com.wutuo.child.provider.enums.RollCallState;
import com.wutuo.roster.api.response.RosterResponse;
import com.wutuo.tag.api.response.TagResponse;
import com.wutuo.wtservice.api.response.ServiceEnumResponse;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;

public class RollCallDataConvert {

    private static UserService userService = SpringContextHolder.getBean("userService");

    public static CallVo convertTaskToCallVo(Task task) {

        if (task == null) {
            return null;
        }
        CallVo call = new CallVo();
        call.setId(task.getId());
        call.setName(task.getTaskName());
        call.setTime(task.getTaskTime());
        return call;
    }

    public static List<Long> getUnsignChildId(List<TaskDetail> details) {

        if (CollectionUtils.isEmpty(details)) {
            return Collections.emptyList();
        }

        List<Long> unSignChildIds = new ArrayList<>();
        for (TaskDetail taskDetail : details) {
            unSignChildIds.add(taskDetail.getUserId());
        }

        return unSignChildIds;
    }

    public static Set<Long> getTeacherId(List<TaskDetail> details) {

        if (CollectionUtils.isEmpty(details)) {
            return Collections.emptySet();
        }

        Set<Long> userIds = new HashSet<>();
        for (TaskDetail taskDetail : details) {
            userIds.add(taskDetail.getCreateBy());
        }
        return userIds;
    }

    public static List<ListSignItem> convertTaskDetailsToSignItem(List<TaskDetail> taskDetails, Map<String, RosterResponse> rosterMap,
                                                                  Map<Long, User> userInfoMap) {

        if (CollectionUtils.isEmpty(taskDetails)) {
            return Collections.emptyList();

        }

        List<ListSignItem> result = new ArrayList<>();
        for (TaskDetail item : taskDetails) {
            Long childId = item.getUserId();
            if (childId == null) {
                continue;
            }
            RosterResponse roster = rosterMap.get(String.valueOf(childId));
            if (roster == null) {
                continue;
            }

            // Get child tags
            List<CallTagVo> callTags = convertTaskResponseToCallTag(roster.getTag());

            // Get child service
            List<CallTypeVo> callTypes = convertServiceResponseToCallType(roster.getTgTypeList());

            // Judge isLate state
            RollCallState signState = RollCallState.get(item.getState());
            boolean isLate = RollCallState.LATE.equals(signState);

            // Get teacherInfo
            User user = userInfoMap.get(item.getCreateBy() == null ? 0 : item.getCreateBy());
            TeacherVo teacher = new TeacherVo();
            if (null != user) {
                teacher.setId(user.getId());
                teacher.setName(user.getName());
            }

            ListSignItem record = new ListSignItem();
            record.setImg(roster.getPhoto());
            record.setLate(false);
            record.setName(roster.getName());
            record.setTags(callTags);
            record.setTypes(callTypes);
            record.setYear(roster.getYear());
            record.setChildId(childId);
            record.setClassName(roster.getGrade());
            record.setSignTime(item.getCreateDate());
            record.setLate(isLate);
            record.setTeacher(teacher);

            result.add(record);
        }

        return result;
    }

    public static List<ListSignItem> convertToUnsignList(List<Long> unSignChildIds, Map<String, RosterResponse> rosterMap) {

        if (CollectionUtils.isEmpty(unSignChildIds)) {
            return Collections.emptyList();
        }

        List<ListSignItem> result = new ArrayList<>();
        for (Long childId : unSignChildIds) {
            RosterResponse roster = rosterMap.get(childId.toString());
            if (roster == null) {
                continue;
            }

            // Get child tags
            List<CallTagVo> callTags = convertTaskResponseToCallTag(roster.getTag());

            // Get child service
            List<CallTypeVo> callTypes = convertServiceResponseToCallType(roster.getTgTypeList());

            ListSignItem record = new ListSignItem();
            record.setImg(roster.getPhoto());
            record.setLate(false);
            record.setName(roster.getName());
            record.setTags(callTags);
            record.setTypes(callTypes);
            record.setYear(roster.getYear());
            record.setChildId(childId);
            record.setClassName(roster.getGrade());
            record.setSignTime(null);
            record.setLate(false);
            record.setTeacher(null);

            result.add(record);
        }
        return result;
    }

    public static Map convertToSignList(List<Long> childIds, Map<String, RosterResponse> rosterMap, Map<String, TaskDetail> signRecordMap) {

        if (CollectionUtils.isEmpty(childIds)) {
            return Collections.emptyMap();
        }

        Map mapResult = new HashMap();
        // 误点人数
        int wdrs = 0;
        List<ListSignItem> signRecords = new ArrayList<>();
        List<ListSignItem> unsignRecords = new ArrayList<>();
        for (Long id : childIds) {
            RosterResponse roster = rosterMap.get(String.valueOf(id));
            if (roster == null) {
                continue;
            }
            ListSignItem item = new ListSignItem();
            item.setImg(roster.getPhoto());
            item.setLate(false);
            item.setName(roster.getName());

            List<TagResponse> tags = roster.getTag();
            if (CollectionUtils.isNotEmpty(tags)) {
                item.setTags(convertTaskResponseToCallTag(tags));
            }

            List<ServiceEnumResponse> serviess = roster.getTgTypeList();
            if (CollectionUtils.isNotEmpty(serviess)) {
                item.setTypes(convertServiceResponseToCallType(serviess));
            }
            item.setYear(roster.getYear());
            item.setChildId(id);
            item.setClassName(roster.getGrade());

            // 是否误签
            if (signRecordMap != null && signRecordMap.get(id.toString()) != null) {
                TaskDetail signRecord = signRecordMap.get(id.toString());
                RollCallState rollCallState = RollCallState.get(signRecord.getState());
                switch (rollCallState) {
                    case LATE:
                        item.setLate(true);
                        item.setSignTime(signRecord.getCreateDate());
                        wdrs = wdrs + 1;
                        signRecords.add(item);
                        break;
                    case INTIME:
                        signRecords.add(item);
                        item.setSignTime(signRecord.getCreateDate());
                        break;
                    case MISS:
                        // NOTHING
                        break;
                    default:
                        break;
                }

                TeacherVo teacherVo = new TeacherVo();
                Long signRecordCreateBy = signRecord.getCreateBy() == null ? 0 : signRecord.getCreateBy();
                User userTeache = userService.getUserById(signRecordCreateBy);
                teacherVo.setId(roster.getTeacherId());
                if (userTeache != null) {
                    teacherVo.setName(userTeache.getName());
                }
                item.setTeacher(teacherVo);
            } else {
                unsignRecords.add(item);
            }

        }
        mapResult.put("signed", signRecords);
        mapResult.put("unsign", unsignRecords);
        mapResult.put("wdrs", wdrs);
        return mapResult;
    }

    public static AddRollCallTaskResponse buildAddRollCallTaskResponse(Task task, int inTimeNum, int totalNum) {

        if (task == null) {
            return new AddRollCallTaskResponse();
        }
        AddRollCallTaskResponse response = new AddRollCallTaskResponse();

        response.setTaskId(task.getId());
        response.setTaskName(task.getTaskName());
        response.setTaskTime(task.getTaskTime());
        response.setInTimeStudentNum(inTimeNum);
        response.setTotalStudentNum(totalNum);

        return response;
    }

    /**
     * convert child tags
     *
     * @param tags
     * @return
     */
    private static List<CallTagVo> convertTaskResponseToCallTag(List<TagResponse> tags) {

        if (CollectionUtils.isEmpty(tags)) {
            return Collections.emptyList();
        }

        List<CallTagVo> callTags = new ArrayList<>();
        for (TagResponse tagResponse : tags) {
            CallTagVo tag = new CallTagVo();
            tag.setId(tagResponse.getId());
            tag.setName(tagResponse.getTagName());
            callTags.add(tag);
        }
        return callTags;
    }

    /**
     * convert child service
     *
     * @param rosterServices
     * @return
     */
    private static List<CallTypeVo> convertServiceResponseToCallType(List<ServiceEnumResponse> rosterServices) {

        if (CollectionUtils.isEmpty(rosterServices)) {
            return Collections.emptyList();
        }

        List<CallTypeVo> types = new ArrayList<>();
        for (ServiceEnumResponse vo : rosterServices) {
            CallTypeVo record = new CallTypeVo();
            record.setId(vo.getId());
            record.setName(vo.getName());
            types.add(record);
        }

        return types;

    }

    public static List<SignDetailItem> convertToSignDetailList(List<TaskDetail> taskDetails, Map<String, RosterResponse> rosterMap,
                                                               Map<Long, User> userInfoMap) {

        if (CollectionUtils.isEmpty(taskDetails)) {
            return Collections.emptyList();

        }

        List<SignDetailItem> result = new ArrayList<>();
        for (TaskDetail item : taskDetails) {
            Long childId = item.getUserId();
            if (childId == null) {
                continue;
            }

            RosterResponse roster = rosterMap.get(String.valueOf(childId));
            if (roster == null) {
                continue;
            }

            // Get child tags
            List<CallTagVo> callTags = convertTaskResponseToCallTag(roster.getTag());

            // Get child service
            List<CallTypeVo> callTypes = convertServiceResponseToCallType(roster.getTgTypeList());

            // Judge isLate state
            RollCallState signState = RollCallState.get(item.getState());
            boolean isLate = RollCallState.LATE.equals(signState);

            // Get teacherInfo
            User user = userInfoMap.get(item.getCreateBy() == null ? 0 : item.getCreateBy());
            TeacherVo teacher = new TeacherVo();
            if (null != user) {
                teacher.setId(user.getId());
                teacher.setName(user.getName());
            }

            // TODO: Catelog subRecord type by next version
            List<SignDetailSubVo> detail = new ArrayList<>();
            SignDetailSubVo subRecord = new SignDetailSubVo();
            subRecord.setActionName("签到");
            subRecord.setActionType(SignActionType.SIGN.getValue());
            subRecord.setTeacher(teacher);
            subRecord.setSignTime(item.getCreateDate());
            subRecord.setRecordId(item.getId());
            detail.add(subRecord);

            SignDetailItem record = new SignDetailItem();
            record.setUserImg(roster.getPhoto());
            record.setLate(false); // TODO: check this state
            record.setUserName(roster.getName());
            record.setTags(callTags);
            record.setTypes(callTypes);
            record.setYear(roster.getYear());
            record.setChildId(childId);
            record.setClassName(roster.getGrade());
            record.setLate(isLate);
            record.setSignDetail(detail);

            result.add(record);
        }

        return result;
    }
}
